
#include <bits/stdc++.h>
using namespace std;
const int MAXN=3e3+10;
const int INF=1e-9;
inline int read(){
    int w=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        w=w*10+ch-'0';
        ch=getchar();
    }
    return w*f;
}
struct node{
    int pos,v,a;
}A[MAXN];
int T,Pos[MAXN];
bool Map[MAXN][MAXN];
int NN[MAXN];
int N,M,L,V;
int Num,Ans,opt;
bool check;
int HAD[MAXN];
bool find(double x,double y){
    for(int i=1;i<=M;i++){if(double(Pos[i])>=x&&double(Pos[i])<y){return true;}}
    return false;
}
signed main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    T=read();
    while(T--){
        memset(A,0,sizeof(A));
        memset(Pos,0,sizeof(Pos));
        memset(Map,0,sizeof(Map));
        memset(NN,0,sizeof(NN));
        memset(HAD,0,sizeof(HAD));
        Num=0; Ans=0;
        N=read(); M=read(); L=read(); V=read();
        for(int i=1;i<=N;i++){A[i].pos=read(); A[i].v=read(); A[i].a=read();}
        for(int i=1;i<=M;i++){Pos[i]=read();}
        for(int i=1;i<=N;i++){
            if(A[i].a>=0&&A[i].v>V){
                for(int j=1;j<=M;j++){if(Pos[j]>=A[i].pos){Map[i][j]=true;}}
                Num++;
            }
            if(A[i].a<0&&A[i].v>V){
                check=false;
                double xx=(V*V-A[i].v*A[i].v)/(2*A[i].a);
                for(int j=1;j<=M;j++){
                    if(double(Pos[j])>=A[i].pos&&double(Pos[j])<double(A[i].pos)+xx){
                       Map[i][j]=true; 
                       check=true;
                   }
                }
                if(check){Num++;}
            }
            if(A[i].a>0&&A[i].v<V){
                check=false;
                double xx=(V*V-A[i].v*A[i].v)/(2*A[i].a);
                if(double(A[i].pos)+xx<=double(L)){
                    for(int j=1;j<=M;j++){
                        if(double(Pos[j])>double(A[i].pos)+xx){
                            Map[i][j]=true;
                            check=true;
                        }
                    }
                }
                if(check){Num++;}
            }
        }
        for(int j=1;j<=M;j++){
            check=false;
            for(int i=1;i<=N;i++){
                if(Map[i][j]==true&&HAD[i]==0){
                    check=true;
                }
            }
            if(check){
                NN[++opt]=j;
                for(int i=1;i<=N;i++){if(Map[i][j]){HAD[i]++;}}
            }
        }
        Ans=opt;
        for(int i=1;i<=opt;i++){
            check=true;
            for(int j=1;j<=N;j++){if(Map[j][NN[i]]==true&&HAD[j]==1){check=false;}}
            if(check){
                for(int j=1;j<=N;j++){if(Map[j][NN[i]]==true){HAD[j]--;}}
                Ans--;
            }
        }
        printf("%d %d\n",Num,M-Ans);
    }
    return 0;
}